use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::io::Write;

pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
    let contents = fs::read_to_string(config.filename)?;
    search_all(&contents, config.tofilename.as_str())?;
    Ok(())
}

pub struct Config {
    filename: String,
    tofilename: String,
}
impl Config {
    pub fn new(args: &[String]) -> Result<Config, &'static str> {
        if args.len() < 3 {
            return Err("没有足够的参数");
        }
        let filename = args[1].clone();
        let tofilename = args[2].clone();
        Ok(Config {
            filename,
            tofilename,
        })
    }
}

pub fn search_all<'a>(contents: &'a str, tofilename: &str) -> Result<(), Box<dyn Error>> {
    let mut results = HashMap::new();

    for line in contents.lines() {
        let mut key = String::from("");
        let mut value: i32 = 0;
        let mut item = parse_line(line);

        if let Some(v) = item.pop() {
            // value = v.parse::<i32>().unwrap();
            if let Ok(v) = v.parse::<i32>() {
                value = v;
            }
        }
        for k in item {
            key = format!("{}{}", key, k);
        }

        if results.contains_key(&key) {
            if let Some(v) = results.get(&key) {
                value += v;
            }
        }
        results.insert(key, value);
    }
    fs::write(tofilename, "")?;
    // let mut file = fs::OpenOptions::new().append(true).open(tofilename).expect("打不开文件!");
    let mut file = fs::OpenOptions::new().append(true).open(tofilename)?;
    for (k, v) in results {
        let ret_text = format!("{}\t{}\n", k, v);
        // file.write_all(ret_text.as_bytes()).expect("写入失败");
        file.write_all(ret_text.as_bytes())?;
    }
    Ok(())
}

pub fn parse_line<'a>(contents: &'a str) -> Vec<&'a str> {
    contents.split_whitespace().collect()
}
